home *** CD-ROM | disk | FTP | other *** search
- ; Socket.s
- ; : Source code to SocketFS
- ; : BSD sockets as files!
- ;
- ; Created : 04-07-97
- ; Author : R G Gammans
- ;
- ; Modified: 18-08-97
-
-
- ; SocketFS - BSD sockets filing system for RISC-OS.
- ; Copyright (C) 1997 Roger G Gammans
- ;
- ; This program is free software; you can redistribute it and/or modify
- ; it under the terms of the GNU General Public License as published by
- ; the Free Software Foundation; either version 2 of the License, or
- ; (at your option) any later version.
- ;
- ;
- ; This program is distributed in the hope that it will be useful,
- ; but WITHOUT ANY WARRANTY; without even the implied warranty of
- ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ; GNU General Public License for more details.
- ;
- ; You should have received a copy of the GNU General Public License
- ; along with this program; if not, write to the Free Software
- ; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ;
- ; Author: R Gammans <rgammans@compsurg,demon.co.uk>
- ; Snailmail : 20 Trenches Rd, Crowborough, E Sussex, TN6 1ES UK.
- ;
-
-
- GET AsmLib:s.DebugHdr
-
- ;Debug SETL {TRUE}
- Debug SETL {FALSE}
-
- GET AsmLib:h.SWINames
- GET AsmLib:h.FSControls
- GET AsmLib:h.psrFlags
- GET AsmLib:h.sockConsts
-
- IMPORT |__RelocCode|
- IMPORT |_clib_initialisemodule|
- IMPORT |_clib_finalisemodule|
- IMPORT |malloc|
- IMPORT |memcpy|
- IMPORT |makeSocket|
- IMPORT |inithandlerlist|
- IMPORT |_Lib$Reloc$Off$DP|
-
- AREA |!!Module$Header|, CODE, READONLY
-
- Pc RN R15
- pc RN R15
- PC RN R15
-
-
- tempbyte * 0 ;Use first byte of workspace as dumping ground.
-
-
-
- SocketFSMod_BaseAddr
-
- DCD 0
- DCD Socket_Init - SocketFSMod_BaseAddr
- DCD Socket_Die - SocketFSMod_BaseAddr
- DCD 0 ;Later version will probaly
- ;handle services
- DCD Socket_Title - SocketFSMod_BaseAddr
- DCD Socket_HelpStr - SocketFSMod_BaseAddr
- DCD Socket_HC_Table- SocketFSMod_BaseAddr
- DCD 0
- DCD 0
- DCD 0
- DCD 0
-
- Socket_DoSWI
- Socket_SWITable
- DCD 0,0
- Socket_Title
- DCB "SocketFS",0
- Socket_HelpStr DCB "SocketFS",9,"0.01 (18 Aug 1997) © Roger Gammans. Distribute as per GPL V2",0
- ALIGN
- Socket_HC_Table DCB "SocketFS",0
- ALIGN
- DCD socket_selectfs- SocketFSMod_BaseAddr
- DCD 0
- DCD 0
- DCD socket_selectfs_help- SocketFSMod_BaseAddr
- DCD 0
-
-
- socket_selectfs_help
- DCB &1b,1,13,13,"This command ",&1b,28,"s",&1b,2,"socket ",&1b,4,0
-
- socket_selectfs ;Nicked form PRMs (RO3) P.2-524
- STMFD R13!,{R14}
- MOV R0,#FSControl_selectFS ;14
- ADR R1,socket_fsname
- SWI XOS_FSControl
- LDMFD R13!, {PC}
-
- Socket_Init
- STMFD R13!,{R7-R11,r14}
- MOV R10,R13,LSR #20 ;Which MB boundary is the stack on...
- MOV R10,R10,LSL #20 ;point R10 directly at booundary...
- LDMIA R10,{R4,R5} ;Get relocation for other C SVC modules....
- STMFD R13!,{R4,R5} ;hold it safley on top of stack!
- STMFD R13!,{R12} ;R12 corruptable under APCS-R....
- ; BL __RelocCode ;Do any relocations and return.
- BL _clib_initialisemodule ;We use 'C' functions so...
- DBSET DebugOn :OR: UseTracker
- DBF "\fStarting\n-sp = &%dw\n"
- MOV R0,#12 ;12 bytes ws.
- BL malloc ;Allocate it!
- MOVS R6,R0 ;Set flags from R0
- BEQ socket_nomem ;Can't alloc ret eith error
- LDMFD R13!,{r12} ;Get R12 Back..
- LDR R12,[R12] ;Get ws frm private word...
- STR R12,[R6,#4] ;Store stub's ws ptr.
- DBF "Doing AF_INIT (sic) ws@ %4w, %cw\n"
- BL inithandlerlist ;Initialise list of known address families
- DBF "Done AF_INIT ws's @ %4w, %cw\n"
- BL socket_clibstackunmunge ;Return stack to SVC std..
- DBF "Done Stack unmunge...sp = &%dw\n"
- MOV R3,R6 ;Pass our ws to FS_control as ws ptr
- MOV R0,#FSControl_AddFS
- ADR R1,SocketFSMod_BaseAddr
- MOV R2,# socket_FSinfo - SocketFSMod_BaseAddr
- DBF "About to call SWI...\n"
- SWI XOS_FSControl ;Add FS info to RISC-OS
- DBF "Done SWI ADDFS\n"
- LDMFD R13!,{R7-r11,pc}
-
- Socket_Die
- LDR R12,[R12] ;Get pointer to workspace.
- STMFD R13!,{R14} ;Save R14 on stack so we can use SWIs
- MOV R0,#FSControl_removeFS
- ADR R1,socket_fsname
- SWI XOS_FSControl ;Tell RISC-OS FS is going...
- BL socket_clibstackmunge
- MOV R0,R12
- BL _clib_finalisemodule
- BL socket_clibstackunmunge
- CMP PC,#0 ;Clear V flag.
- LDMFD R13!,{pc} ;Done go home.
-
- socket_nomem
- LDMFD R13!,{R12}
- LDMFD R13!,{R7-R11,R14}
- ADR R0,socket_nomemmsg
- ORRS PC,R14,#V_Bit
- socket_nomemmsg
- DCD &001FF01
- DCB "No memory for filing system",13,0
- ALIGN
-
-
- ;Need to find I bettr way of commenting these bit fields.
- ;socket_info_word EQU 1 << 31+
- ; 1 << 30 + ;Streams are interactive
- ; 0 << 29 + ;FS does support null length names;
- ; 1 << 28 + ;FS should be asked to open Non-existent files
- ; 0 << 27 + ;Use FSEntry Args 255 to flush
- ; 1 << 26 + ;We support FS_File 9
- ; 1 << 25 + ;We support FS_Func 20
- ; 0 << 24 + ;Currently reserved.
- ; 0 << 23 + ;we don't support ImageFS extension
- ; 0 << 22 + ;Do pass & and % in path
- ; 1 << 21 + ;Need not store dira
- ; 1 << 20 + ;Use Open/Get/Close in pref to File 255
- ; 1 << 19 + ;Use Open/Get/Close in pref to File 0
- ; 1 << 18 + ;Use FS_entry 9 instead of FS_Entry File
- ; 0 << 17 + ;Extra info word not present
- ; 0 << 16 + ;FS writable
- ; &0 << 8 + ;No defititnve limit to open files.
- ; 1 << 31+\
-
- socket_info_word EQU 1 << 31+\
- 1 << 30+\
- 0 << 29+\
- 1 << 28+\
- 0 << 27+\
- 1 << 26+\
- 1 << 25+\
- 0 << 24+\
- 0 << 23+\
- 0 << 22+\
- &F << 18+\
- 0 << 17+\
- 0 << 16+\
- 0 << 8+\
- &00FF ;SocketFS Number
-
-
- socket_FSinfo
- DCD socket_fsname - SocketFSMod_BaseAddr
- DCD startup_msg - SocketFSMod_BaseAddr
- DCD socket_open - SocketFSMod_BaseAddr
- DCD socket_read - SocketFSMod_BaseAddr
- DCD socket_write - SocketFSMod_BaseAddr
- DCD socket_args - SocketFSMod_BaseAddr
- DCD socket_close - SocketFSMod_BaseAddr
- DCD socket_file - SocketFSMod_BaseAddr
- DCD socket_info_word
- DCD socket_Func - SocketFSMod_BaseAddr
- DCD socket_GBPB - SocketFSMod_BaseAddr
- DCD 0
-
- socket_fsname
- DCB "SocketFS",0
- ALIGN
- startup_msg
- DCB "Internet Filesystem",0
-
- ALIGN
-
-
- socket_open
- STMFD R13!,{R14}
- DBF "File open entry called\n"
- MOVS R0,R6 ;Copy special field over
- DBF " - spcf = %0s\n" , NE
- DBF " - no special field\n", EQ
- DBF " - fname -= %1s\n" ;reason code...
- LDR R12,[R12,#4] ;Get stubs ws.
- BL socket_clibstackmunge ;Set stack up for Clib.
- BL makeSocket ;Call C filename processor
- ;This give socket in R0
- BL socket_clibstackunmunge
- ; or -1 if no socket opened
- ADD R1,R0,#1 ;Make my handle the socket number +1
- ; conveiently 0 now indicates file not found
-
- MOV R2,#0 ;Unbuffered...(actually internet mod
- ;will buffer).
- MOV R3,#0 ;File extent not used...
- MOV R4,#0 ;No buffer space allocated..
- MOV R0,#&D8000000 ;File Info word
-
- ;File set as readablr,writeable,Stream device and interactive
-
- LDMFD R13!,{PC}^ ;Finish...
-
-
- socket_read
- STMFD R13!,{R14}
- DBF "File read entry called for socket %1w\n"
- SUB R0,R1,#1 ;Put socket number in R0.
- SUB R13,R13,#4 ;resevre 1w ws on stack.
- MOV R1,R13 ;Put buffer in R1..
- MOV R2,#1 ;Put buff size in R2
-
- ;Ignore file offset as we have streams...
- SWI XSocket_Read ;Call Internet module..
- LDRVC R0,[R13] ;If no error get byte from buff
- ADD R13,R13,#4 ;Release ws.
- LDMVCFD R13!,{PC}^
-
- LDR R1,[R0] ;Get Errno
- DBF "Socket Err %1w\n"
- CMP R1,#EWOULDBLOCK ;Is Rx/Tx limits.
- LDMEQFD R13!,{R14} ;Get lr early so we can set flags
- MOV R0,#0 ;Retrun 0 char - t
- ORREQ PC,R14,#C_Bit
- ;Now we have to work out what to do in the case of other errs!.
- LDMFD R13!,{R14} ;Return with V set!., m
- ORR PC,R14,#V_Bit ;Set V flag
- socket_write
- STMFD R13!,{R1-R2,R14}
- DBF "File write entry called\n - R0 %0b\n - R1 %1w\n"
- SUB R13,R13,#4 ;Resevre 1 w one stack.
- STR R0,[R13] ;Store byte to send
- SUB R0,R1,#1 ;Put socket number in R0.
- MOV R1,R13 ;Put buffer in R1..
- MOV R2,#1 ;Put buff size in R2
- SWI XSocket_Write ;Call Internet module..
- ADD R13,R13,#4 ;Release stack ws.
- LDMFD R13!,{R1-R2,PC}
-
-
- socket_close STMFD R13!,{R14}
- DBF "File close entry called\n"
- SUB R0,R1,#1 ;Put Socket in R0
-
- ;Ignore other stuff as meaningless.
- SWI XSocket_Close ;Call internet module
- LDMFD R13!,{PC}
-
- socket_GBPB ;Optimized multibyte get and put routines.....
- ;In fact in our case almost simpler than the single byte
- ;ones
-
- STMFD R13!,{R0-R4,R14}
- DBF "File gpbp entry called op no - %0w\n"
-
- CMP R0,#3 ;Check reason code...
- BGE socket_multiget ;Do get mutliple..
-
- ;put multiple . move regs to place for socket call
- SUB R0,R1,#1
- MOV R1,R2
- MOV R2,R3
- SWI XSocket_Write
- BVS socket_gbpb_handError
- MOV R5,R0
- LDMFD R13!,{R0-R4,R14}
- ADD R2,R2,R5 ;Compute new buff ptr
- SUB R3,R3,R5 ;Compute new buff free size
- ADD R4,R4,R5 ;Compute new file pointer!
- MOVS PC,R14 ;Return to caller
-
- socket_multiget
-
- ;get multiple . move regs to place for socket call
- SUB R0,R1,#1
- MOV R1,R2
- MOV R2,R3
- SWI XSocket_Read
- BVS socket_gbpb_handError
- MOV R5,R0
- LDMFD R13!,{R0-R4,R14}
- ADD R2,R2,R5 ;Compute new buff ptr
- SUB R3,R3,R5 ;Compute new buff free size
- ADD R4,R4,R5 ;Compute new file pointer!
- MOVS PC,R14 ;Return to caller
-
- socket_gbpb_handError
- LDR R1,[R0] ;Get Errno
- CMP R1,#EWOULDBLOCK ;Is Rx/Tx limits.
- LDMEQFD R13!,{R0-R4,PC}^ ;Return doing nothing
- ;Fileswitch will work out what to tell client!
-
- ;Now we have to work out what to do in the case of other errs!.
- MOV R5,R0 ;Save errrblk ptr..
- LDMFD R13!,{R0-R4,R14} ;get orignal regs..
- MOV R0,R5 ;restore errblk ptr
- ORRS PC,R14,#V_Bit ;return with V set.
-
-
- socket_args ;Handle wodges of OS_Args codes here!
- STMFD R13!,{R0-R4,R14} ;Store Registers!
- DBF "FS_Entry Args %0w called\n"
- CMP R0,#10
- ADDLE PC,PC,R0,LSL #2 ;Use old fashionned
- ;Swi dispatch trick
- B socket_unknownCall
-
- B socket_returnZero
- LDMFD R13!,{r0-R4,PC} ;Ignore ARgs 1
- B socket_returnZero
- LDMFD R13!,{R0-R4,PC} ;Ignore Args 3
- B socket_allocedsize
- B socket_EOFcheck ;Is TCP connection open?
- B socket_Flush ;Not called but triv to code!
- B socket_Extent
- LDMFD R13!,{R0-R4,PC} ;Not suported .. unbuffered
- B socket_returnZeros
- LDMFD R13!,{R0-R4,PC} ;If you've implemented an imagefs over socketfs I'd be shocked!
-
- socket_allocedsize
- LDMFD R13!,{R0-R4,R14}
- MOV R2,#1
- MOV PC,R14
-
- socket_Extent
- LDMFD R13!,{R0-R4,R14}
- ;What do we need to tell Fileswitch
- MOV R2,#1
- MOV PC,R14
-
- socket_returnZero
- LDMFD R13!,{R0-R4,R14}
- MOV R2,#0 ;Return R2=0
- MOV Pc,R14
-
- socket_returnZeros
- LDMFD R13!,{R0-R4,R14}
- MOV R2,#0 ;Return R2-R3=0.
- MOV R3,R2
- MOV Pc,R14
-
- socket_Flush
- LDMFD R13!,{R0-R4,R14}
- STMFD R13!,{R1-R4,R14}
- SUB R0,R1,#1 ;Get File handle
- ADD R1,R12,#tempbyte
- MOV R2,#0 ;Send 0 octets
- SWI XSocket_Send
- LDMFD R13!,{R1-R4,PC}
-
- socket_EOFcheck
- LDMFD R13!,{R0-R4,R14}
- STMFD R13!,{R14}
- SUB R0,R1,#1 ;Get socket handle
- ADD R1,R12,#tempbyte
- MOV R2,#1 ;Get a byte
- MOV R3,#(MSG_PEEK + MSG_DONTWAIT) ;but don't remove it from the queue
- SWI XSocket_Recv
- LDRVS R1,[R0] ;If err get ErrNo
- MOVS R0,R0 ;IF read()==0
- CMPNE R1,#ECONNRESET ; || ==ECONNRESET
- MOV R2,#0 ; then R2=0
- SUBEQ R2,R2,#1 ; else R2=-1
- LDMFD R13!,{PC}^ ;return!
-
- socket_unknownCall
- ADR R0,socket_unknownCallMsg
- ORRS PC,PC,#V_Bit
- LDMFD R13,{R0-R4,PC}
-
- socket_unknownCallMsg
- DCD &0001FFEE
- DCB "Socketfs doesn't support this call",13
- ALIGN
-
- socket_Func
- STMFD R13!,{R0-R4,R14} ;Store Registers!
- DBF "FS_Entry Func %0w called\n"
- CMP R0,#34
- ADDLE PC,PC,R0,LSL #2 ;Use old fashionned
- ;Swi dispatch trick
- B socket_unknownCall
-
- B socket_DoNothing ;FsEntry_Func 0
- B socket_DoNothing ;FsEntry_Func 1
- B socket_DoNothing ;FsEntry_Func 2
- B socket_DoNothing ;FsEntry_Func 3
- B socket_DoNothing ;FsEntry_Func 4
- B socket_DoNothing ;FsEntry_Func 5
- B socket_DoNothing ;FsEntry_Func 6
- B socket_DoNothing ;FsEntry_Func 7
- B socket_rename ;FsEntry_Func 8
- B socket_DoNothing ;FsEntry_Func 9
- B socket_DoNothing ;FsEntry_Func 10
- B socket_readBoot ;FsEntry_Func 11
- B socket_readDirName ;FsEntry_Func 12
- B socket_readDirName ;FsEntry_Func 13
- B socket_readDir ;FsEntry_Func 14
- B socket_readDir ;FsEntry_Func 15
- B socket_DoNothing ;FsEntry_Func 16
- B socket_annouce ;FsEntry_Func 17
- B socket_DoNothing ;FsEntry_Func 18
- B socket_readDir ;FsEntry_Func 19
- B socket_DoNothing ;FsEntry_Func 20
- B socket_DoNothing ;FsEntry_Func 21
- B socket_DoNothing ;FsEntry_Func 22
- B socket_DoNothing ;FsEntry_Func 23
- B socket_DoNothing ;FsEntry_Func 24
- B socket_readDefects ;FsEntry_Func 25
- B socket_DoNothing ;FsEntry_Func 26
- B socket_readBoot ;FsEntry_Func 27
- B socket_DoNothing ;FsEntry_Func 28
- B socket_DoNothing ;FsEntry_Func 29
- B socket_readFree ;FsEntry_Func 30
- B socket_DoNothing ;FsEntry_Func 31
- B socket_DoNothing ;FsEntry_Func 32
- B socket_readUsage ;FsEntry_Func 33
- B socket_DoNothing ;FsEntry_Func 34
-
-
- ;Some of the calls that seem to come here should never be called anyway.
- ;(at least assuming the PRMs are correct!)
- socket_DoNothing
- LDMFD R13!,{R0-R4,PC}^ ;Return to fileswitch.
-
- socket_rename
- ;Can't Rename sockets so return with error
- LDMFD R13!,{R0-R4,R14} ;Tidy stack
- MOV R0,#1 ;mark rename failed.
- MOVS pc,r14 ;return
-
- socket_DiscBoot
- ;Here we use the 'C' libs memcpy to move our data to Fileswicth
- ;It's overkill for 5 bytes but there an outside chance it
- ;will validate the address for us.
- MOV R1,R2
- ADR R0,socket_DiscMsg
- MOV R2,#socket_DiscMsg - socket_DiscMsgEnd
- BL memcpy
- LDMFD R13!,{R0-R4,PC}
- socket_DiscMsg
- DCB 3,"tcp",0
- socket_DiscMsgEnd
- ALIGN
- socket_readDirName
- ;Will need to implement to support RO2
- B socket_DoNothing
-
- socket_readDir
- ;We essentially show an emtpy directry with
- ;these calls so they can all share a routine.
- LDMFD R13!,{R0-R4,R14} ;Tidy stack,
- MOV R3,#0 ;No records read
- STR R3,[R2] ;Use 0 to terminate buffer
- MVN R4,#0 ;End of directory
- MOVS Pc,R14 ;Return
-
- socket_annouce
- SWI XOS_WriteS
- DCB "Erk! SocketFS",13,0 ;if socketfs is default at
- ALIGN ;boot then you're being clever
- ;or have just hung!
- LDMFD R13!,{R0-R4,PC}
-
- socket_readDefects
- ;OK so the internet has them, but not quite in the way
- ;fileswtich means. So we return an empty defect list.
- MOV R0,#&20000000 ;Load the list terminator
- STR R0,[R2] ;Terminate the list's first word
- LDMFD R13!,{R0-R4,PC}^ ;Preserve regs and return.
-
- socket_readBoot
- LDMFD R13!,{R0-R4,R14} ;Tidy stack
- MOV R2,#0 ;Boot opt=0
- MOVS pc,R14 ;Return.
-
- socket_readFree
- LDMFD R13!,{R0-R4,R14} ;Tidy stack
- MOV R0,#0 ;0 free space
- MOV R1,#0 ;0 cont. free space
- MOV R2,#0 ;0 disc size
- MOVS pc,R14 ;Return.
-
- socket_readUsage
- LDMFD R13!,{R0-R4,R14} ;Tidy stack
- MOV R2,#2 ;Streams have unique address space
- MOVS pc,R14 ;Return.
-
-
-
- socket_file DBF "FS_Entry File %0w called\n"
- TEQ r0, #255
- MOVEQ r0, #10
- CMP r0, #(socket_FileTabEnd - socket_FileTab) / 4
- ADDLE pc, pc, r0, LSL #2
- BICS pc, lr, #V_Bit
-
- socket_FileTab B socket_Save ; Save file
- BICS pc, lr, #V_Bit ; Write catalogue info
- BICS pc, lr, #V_Bit ; Write load address
- BICS pc, lr, #V_Bit ; Write execution address
- BICS pc, lr, #V_Bit ; Write attributes
- B socket_readCat ; Read catalogue info
- BICS pc, lr, #V_Bit ; Delete object
- BICS pc, lr, #V_Bit ; Create file
- BICS pc, lr, #V_Bit ; Create directory
- BICS pc, lr, #V_Bit ; Read catalogue info
- BICS pc, lr, #V_Bit ; Load file
- socket_FileTabEnd
-
-
- socket_Save STMFD R13!, {R0-R1, R4, R14}
- BL socket_open
- BEQ socket_saveErr
- MOV R6,R5
- MOV R1,R0
- MOV R0,#1
- MOV R2,R4
- SUB R3,R5,R4
- socket_saveloop
- BGE socket_saveend
-
- BL socket_GBPB
- BVS socket_saveErr
- MOVS R3,R3
- BEQ socket_saveloop
- socket_saveend MOV R0, R1
- B socket_close
- socket_saveErr
- LDMFD sp!, {R0-R1, r4, R14}
- ADR R0, socket_saveErrMsg
- ORRS pc, lr, #V_Bit
-
-
- socket_saveErrMsg
- DCD &1006702
- DCB "An error ocurring while saving",13,0
- ALIGN
-
- socket_readCat ;Currently we don't check wether this is a fully specified address
- ;with sockets in use (eg. an open file - tcp/udp connection)
- MOV R0,#0 ;File not Found
- BICS R15,R14,#V_Bit ;Return no err.
-
-
- socket_clibstackmunge
- MOV R10,R13,LSR #20 ;Which MB boundary is the stack on...
- MOV R10,R10,LSL #20 ;point R10 directly at booundary...
- LDMIA R10,{R4,R5} ;Get relocation for other C SVC modules....
- STMFD R13!,{R4,R5} ;save old reloc modifiers over fn call
- DBF "Stubs stores relocs @ &%cw\n"
- LDMIB R12, {R4, R5} ;new relocation modifiers
- DBF "C lib reloc directives are &%4w,&%5w\n"
- STMIA R10, {R4, R5} ;set by module init
- MOV fp, #0 ;halt C backtrace here!
-
- DCD |_Lib$Reloc$Off$DP| + &E28AA000 ; This is equivalent of 'ADD r10, r10, #0' + |_Lib$Reloc$Off$DP|
- MOVS Pc,R14
-
- socket_clibstackunmunge
- MOV R10,R13,LSR #20 ;Which MB boundary is the stack on...
- MOV R10,R10,LSL #20 ;point R10 directly at booundary...
- LDMIA R10,{R4,R5} ;Check so we can match later!
- DBF "C lib reloc directives are &%4w,&%5w\n"
- LDMFD R13!,{R4,R5} ;Get relocation for other C SVC modules....
- STMIA R10,{R4,R5} ;put it back where it came from!
- MOVS Pc,R14
-
- END
-